/*
 * Copyright 2011 es-planning Inc.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package jp.arctos.ursus;

import java.io.IOException;
import java.util.ArrayList;
import java.util.List;

import javax.realtime.RealtimeThread;

import jp.arctos.ursus.starter.EntryProperty;
import jp.arctos.ursus.starter.UrsusEntry;


public class UrsusEngine {
    private static ArrayList<UrsusEventListener> listenerList;
    private static UrsusState state;
    private UrsusLoader loader;
    
    private UrsusEngine() throws IOException {
        state = UrsusState.INITIAL;
        loader = new UrsusLoader();
    }
    
    public static synchronized void addUrsusEventListener(UrsusEventListener listener) {
        if (listener == null) {
            throw new IllegalArgumentException();
        }
        if (listenerList == null) {
            listenerList = new ArrayList<UrsusEventListener>();
        }
        listenerList.add(listener);
    }
    
    public static synchronized void shutdown() {
        if (state != UrsusState.SHUTDOWN && listenerList != null) {
            state = UrsusState.SHUTDOWN;
            for (UrsusEventListener listener : listenerList) {
                listener.shutdown();
            }
        }
    }
    
    public List<Class<?>> getEntryList() throws ClassNotFoundException {
        ArrayList<Class<?>> list = new ArrayList<Class<?>>();
        list.add(Class.forName(
        		EntryProperty.INSTANCE.get("FRAMEWORK_ENTRY"),
        		true,
        		loader.getFrameworkLoader()));
        list.add(Class.forName(
        		EntryProperty.INSTANCE.get("APPLICATION_ENTRY"),
        		true,
        		loader.getApplicationLoader()));
        return list;
    }

    private void start() throws IOException, ClassNotFoundException {
        // Initialization for Ursus
        loader.load();
        Runtime.getRuntime().addShutdownHook(new RealtimeThread() {
            @Override
            public void run() {
                shutdown();
            }
        });
        
        // Initialization for User Application
        List<Class<?>> entryList;
        try {
            entryList = getEntryList();
            for (int i = 0; i < entryList.size(); i++) {
                Class<?> entryClass = entryList.get(i);
                UrsusEntry entry = (UrsusEntry) entryClass.newInstance();
                entry.startup();
            }
            state = UrsusState.WORK;
        } catch (Throwable t) {
            t.printStackTrace();
            shutdown();
        }
    }
    
    public static void main(String[] args) {
        UrsusEngine engine;
        try {
            engine = new UrsusEngine();
            engine.start();
        } catch (IOException e) {
            e.printStackTrace();
        } catch (ClassNotFoundException e) {
            e.printStackTrace();
        }
    }
}
